﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CloudStorageLight.Core
{
    public class FarmControl : TableEntity
    {
        public FarmControl()
        {
            this.PartitionKey = "";
            this.RowKey = "";
            this.PrimaryServerHaertBeat = DateTime.MinValue;
        }
        public string PrimaryServerName { get; set; }

        public DateTime PrimaryServerHaertBeat { get; set; }

        public static void WritePrimaryServerHaertBeat(string connectionString)
        {
            var serverName = Environment.MachineName;
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
            TableBatchOperation batchOperation = new TableBatchOperation();
            var table = tableClient.GetTableReference("FarmControl");
            table.CreateIfNotExists();

            var inst = GetPrimaryServer(connectionString, 0);

            if (inst == null || inst.PrimaryServerName == serverName || inst.PrimaryServerHaertBeat.AddMinutes(3) < DateTime.UtcNow)
            {
                inst = inst ?? new FarmControl();
                inst.PrimaryServerName = serverName;
                inst.PrimaryServerHaertBeat = DateTime.UtcNow;
                batchOperation.InsertOrReplace(inst);
                table.ExecuteBatch(batchOperation);
            }
        }

        public static FarmControl GetPrimaryServer (string connectionString, int delay = 1)
        {
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
            TableBatchOperation batchOperation = new TableBatchOperation();
            var table = tableClient.GetTableReference("FarmControl");
            table.CreateIfNotExists();

            var query = new TableQuery<FarmControl>();
            query = query.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ""));
            query = query.Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, ""));
            var list = table.ExecuteQuery(query);
            var item = list.FirstOrDefault();
            //Heart Beatへの同時書き込みがあった場合に最終決定するために書き込み後１秒間まって再度読み出すようにする
            if (item == null || item.PrimaryServerHaertBeat.AddSeconds(delay) > DateTime.UtcNow) return null;
            return item;
        }


        public static bool IsPrimaryServer(string connectionString)
        {
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
            TableBatchOperation batchOperation = new TableBatchOperation();
            var table = tableClient.GetTableReference("FarmControl");
            table.CreateIfNotExists();

            var query = new TableQuery<FarmControl>();
            query = query.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ""));
            query = query.Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, ""));
            var list = table.ExecuteQuery(query);
            var item = list.FirstOrDefault();
            return item != null && item.PrimaryServerName == Environment.MachineName;
        }
    }
}
